﻿using System;
using System.ComponentModel;
using System.ComponentModel.Composition.Hosting;
using System.Diagnostics.CodeAnalysis;

#if !SILVERLIGHT4

using System.Threading.Tasks;

#endif

namespace Songhay.Composition
{
    /// <summary>
    /// Static members for MEF Composition.
    /// </summary>
    public static partial class CompositionUtility
    {
        /// <summary>
        /// Gets the current deployment catalog.
        /// </summary>
        /// <returns>
        /// Returns a new instance of the <see cref="DeploymentCatalog"/> class
        /// using assemblies in the current XAP.
        /// </returns>
        public static DeploymentCatalog GetCurrentDeploymentCatalog()
        {
            return new DeploymentCatalog();
        }

        /// <summary>
        /// Downloads the catalog.
        /// </summary>
        /// <param name="location">The location.</param>
        [SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope",
            Justification = "Reliable disposal depends on callers.")]
        public static DeploymentCatalog DownloadCatalog(Uri location)
        {
            return DownloadCatalog(location, null);
        }

        /// <summary>
        /// Downloads the catalog.
        /// </summary>
        /// <param name="location">The location.</param>
        /// <param name="downloadCompleteAction">The download complete action.</param>
        [SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope",
            Justification = "Reliable disposal depends on callers.")]
        public static DeploymentCatalog DownloadCatalog(Uri location,
            Action<object, AsyncCompletedEventArgs> downloadCompleteAction)
        {
            var catalog = new DeploymentCatalog(location);

            if(downloadCompleteAction != null)
                catalog.DownloadCompleted += (s, args) => downloadCompleteAction.Invoke(s, args);

            catalog.DownloadAsync();
            return catalog;
        }

#if !SILVERLIGHT4

        /// <summary>
        /// Downloads the catalog
        /// in a <see cref="System.Threading.Task"/>.
        /// </summary>
        /// <param name="location">The location.</param>
        /// <param name="downloadCompleteAction">The download complete action.</param>
        [SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope",
            Justification = "Reliable disposal depends on callers.")]
        public static Task<DeploymentCatalog> DownloadCatalogAsync(Uri location)
        {
            return DownloadCatalogAsync(location, null);
        }

        /// <summary>
        /// Downloads the catalog
        /// in a <see cref="System.Threading.Task"/>.
        /// </summary>
        /// <param name="location">The location.</param>
        /// <param name="downloadCompleteAction">The download complete action.</param>
        [SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope",
            Justification = "Reliable disposal depends on callers.")]
        public static Task<DeploymentCatalog> DownloadCatalogAsync(Uri location,
            Action<object, AsyncCompletedEventArgs> downloadCompleteAction)
        {
            var completionSource = new TaskCompletionSource<DeploymentCatalog>();
            var catalog = new DeploymentCatalog(location);

            catalog.DownloadCompleted += (s, args) =>
            {
                if(args.Error != null) completionSource.SetException(args.Error);
                else if(args.Cancelled) completionSource.SetCanceled();
                else
                {
                    completionSource.SetResult(catalog);
                    if(downloadCompleteAction != null)
                        downloadCompleteAction.Invoke(s, args);
                }
            };

            var task = completionSource.Task;
            catalog.DownloadAsync();

            return task;
        }
#endif

    }
}
